/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package graphic;

import java.io.File;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Toolkit;
import java.io.IOException;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import puntajes.Puntajes;

import exceptions.LaserException;
import exceptions.OrigenException;

import juego.Celda;
import juego.Elemento;
import juego.Espejo;
import juego.EspejoDoble;
import juego.EspejoSemi;
import juego.EspejoSimple;
import juego.Tablero;
import juego.Parser;

/**
 *
 * @author maru
 */
public class GamePanel extends JPanel{
	private JButton next;
	private JButton save;
    StartFrame frame;   
    private int n;
    private JPanel currentPanel;
    private String user;
    private StartPanel panel;

	private static final long serialVersionUID = 1L;

	private static final int CELL_SIZE = 30;

	private BoardPanel bp;
	private Tablero[] tables;
	private Tablero table;
	private File[] auxiArchivos;

    public GamePanel(StartFrame sFrame, StartPanel panel, Set<File> levels, String jugador, boolean guardado) {
    	frame=sFrame;    
        this.panel=panel;
        user=jugador;	

        setLayout(null);

        Tablero saved=null;
        if(guardado){
        	Parser pars = new Parser();
        	try {
        		int seleccion;
            	String pathLevel = java.lang.System.getProperty("user.dir") + "\\levels";
        		File fichero=null;
        		JFileChooser fileChooser = new JFileChooser();
            	do{
		    		seleccion = fileChooser.showOpenDialog(fileChooser);
			        if (seleccion == JFileChooser.APPROVE_OPTION)
			        {
			        	fichero = fileChooser.getSelectedFile();
			        }
            	}while(JFileChooser.CANCEL_OPTION==seleccion);
        		if(fichero!=null){
        			if(!fichero.getPath().toString().startsWith(pathLevel)){
        				saved = pars.parser(fichero,true);
        				user=saved.getUser();
        			}
        			else{
        				JOptionPane.showMessageDialog(this,
								"No puede elegir un archivo de la carpeta levels, se cerrara la aplicacion.",
								"Error carpeta levels",
								JOptionPane.ERROR_MESSAGE);
        				System.exit(ERROR);
        			}
        		}
        	} catch (IOException e) {
        		JOptionPane.showMessageDialog(this,
						"El archivo de nivel contiene errores",
						"Error en el archivo",
						JOptionPane.ERROR_MESSAGE);
        		System.exit(ERROR);
			}
        	catch (NumberFormatException e){
        		JOptionPane.showMessageDialog(this,
						"El archivo de nivel contiene errores",
						"Error en el archivo",
						JOptionPane.ERROR_MESSAGE);
        		System.exit(ERROR);
        	}
        }
        
        if( levels.size() == 0 ){
        	JOptionPane.showMessageDialog(this,
					"No hay archivos en la carpeta levels. Cargar archivos para poder jugar.",
					"Error carpeta levels",
					JOptionPane.ERROR_MESSAGE);
			System.exit(ERROR);
        }
        
        Tablero[] t = new Tablero[levels.size()];
		Parser p = new Parser();
		File[] auxi = new File[levels.size()];
		n=0;
        int a = 0;
        for(File archLevel: levels){
			try {
				auxi[a] = archLevel;
				t[a] = p.parser(archLevel,false);
				t[a].setUser(user);
				if(guardado){
					if(t[a].getNivel().equals(saved.getNivel()))
						n=a;
				}
				a++;
			} catch (IOException e) {
				e.printStackTrace();
			}
			catch(NullPointerException e){
				JOptionPane.showMessageDialog(this,
						"Algun archivo de nivel esta mal formado. Se cerrara la aplicacion.",
						"Error",
						JOptionPane.ERROR_MESSAGE);
				System.exit(0);
			}
        }
        	
        auxiArchivos = auxi;
        tables = t;
        
		next = new JButton("Creo que gane!");
		next.setBounds(tables[n].getColumnas() * CELL_SIZE/2 - 100, tables[n].getFilas() * CELL_SIZE + 70, 200, 30);
        add(next);
        
        save = new JButton("Guardar Partida");
		save.setBounds(tables[n].getColumnas() * CELL_SIZE/2 - 100, tables[n].getFilas() * CELL_SIZE + 20, 200, 30);
        add(save);

        if(guardado){
        	currentPanel = proxLevel(0, saved);
        	tables[n] = saved;
        }
        else
        	currentPanel = proxLevel(n,null);
        add(currentPanel);
        
        save.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            	boolean guardo=false;
            	try {
					guardo = tables[n].guardarPartida(auxiArchivos[n].getName().substring(0, auxiArchivos[n].getName().indexOf(".txt")), tables[n].getUser());
            	} catch (IOException e) {
					e.printStackTrace();
				}
				if(guardo){
            		GamePanel.this.frame.remove(GamePanel.this);
	                GamePanel.this.panel.setVisible(true);
	                Toolkit toolkit = getToolkit();
	                Dimension size = toolkit.getScreenSize();
	                GamePanel.this.frame.setBounds(size.width/2 - 400/2, size.height/2 - 400/2, 400, 400);
				}
            }
        });
        
        next.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            	int aux;
            	if((aux=tables[n].validarVictoria())!=-1){
					try {
						Puntajes punt = new Puntajes(auxiArchivos[n].getName().
								substring(0, auxiArchivos[n].getName().indexOf(".txt")).concat(".scores"));
						punt.updatePuntajes(tables[n].getUser(), aux);
					} catch (IOException e) {
						e.printStackTrace();
					}
              		n++;
	            	GamePanel.this.remove(currentPanel);
	            	if(n<tables.length){
	            		currentPanel=proxLevel(n,null);
	            		add(currentPanel);
	            		currentPanel.setVisible(true);
	            	}
	            	else{
	            		GamePanel.this.frame.remove(GamePanel.this);
		                GamePanel.this.panel.setVisible(true);
		                Toolkit toolkit = getToolkit();
		                Dimension size = toolkit.getScreenSize();
		                GamePanel.this.frame.setBounds(size.width/2 - 400/2, size.height/2 - 400/2, 400, 400);
	            	}
	            	updateUI();
            	}
            }
        });
    }
    
    private BoardPanel proxLevel(int n, Tablero t){
    	if(t==null)
    		table = tables[n];
    	else
    		table=t;
        frame.setSize(table.getColumnas() * CELL_SIZE + 20, table.getFilas() * CELL_SIZE + 150);        		
		save.setBounds(table.getColumnas() * CELL_SIZE/2 - 100, table.getFilas() * CELL_SIZE + 20, 200, 30);
		next.setBounds(table.getColumnas() * CELL_SIZE/2 - 100, table.getFilas() * CELL_SIZE + 70, 200, 30);
		bp = new BoardPanel(table.getFilas(), table.getColumnas(), CELL_SIZE);
		bp.setBackground(Color.WHITE);
		bp.setGridColor(Color.GRAY);
		
		Celda celdas[][] = table.getTablero();
		try {
			table.dibujar();
		} catch (LaserException e) {
			e.printStackTrace();
		}
		//DIBUJA LOS LASERS Y LOS ELEMENTOS EN EL TABLERO
		for(int i=0; i<table.getFilas(); i++){
			for(int j=0; j<table.getColumnas(); j++){
				try{
					Set<Image> imgLasers = null;
					imgLasers = celdas[i][j].dibujarLasers();
					for (Image img1 : imgLasers){
						bp.appendImage(i, j, img1);
					}
					bp.appendImage(i, j, celdas[i][j].dibujar());
				}catch(NullPointerException e2){}
			}
		}
		//LISTENER PARA EL CLICK EN EL TABLERO
		bp.setListener(new BoardPanelListener() {
			public void cellClicked(int row, int column) {
				clickListener(row, column);
			}
			public void cellDragged(int sourceRow, int sourceColumn,
					int targetRow, int targetColumn) {
				dragListener(sourceRow, sourceColumn, targetRow, targetColumn);
			}
		});
		return bp;
    }
    
    private void clickListener(int row, int column){
		Celda celdas[][] = table.getTablero();
		boolean noCayoTrampa=true; //si esta en false cayo en trampa
		Class<? extends Elemento> tipo = null;
		if (celdas[row][column]!=null){
			if(celdas[row][column].getElemento()!=null){
				tipo = celdas[row][column].getElemento().getClass();
				if (tipo == EspejoSimple.class || tipo == EspejoSemi.class || tipo==EspejoDoble.class){
					((Espejo) celdas[row][column].getElemento()).sumarRotacion();
					try {
						table.borrarLasersDibujados();
						noCayoTrampa = table.agregarLasers();
						if(!noCayoTrampa){
							JOptionPane.showMessageDialog(this,
									"Ha Perdido!",
									"Suerte en la proxima",
									JOptionPane.ERROR_MESSAGE);
							GamePanel.this.frame.remove(GamePanel.this);
			                GamePanel.this.panel.setVisible(true);
			                Toolkit toolkit = getToolkit();
			                Dimension size = toolkit.getScreenSize();
			                GamePanel.this.frame.setBounds(size.width/2 - 400/2, size.height/2 - 400/2, 400, 400);
			                updateUI();
						}
						for(int i=0; i<table.getFilas(); i++){
							for(int j=0; j<table.getColumnas(); j++){
								try{
									bp.clearImage(i, j);
									Set<Image> imgLasers = null;
									imgLasers = celdas[i][j].dibujarLasers();
									for (Image img1 : imgLasers){
										bp.appendImage(i, j, img1);
									}
									bp.appendImage(i, j, celdas[i][j].dibujar());
								}catch(NullPointerException e2){}
							}
						}
					} catch (OrigenException e) {
						e.printStackTrace();
					} catch (LaserException e) {
						e.printStackTrace();
					}
				}
			}
		}
		bp.repaint();
    }
    
    private void dragListener(int sourceRow, int sourceColumn,int targetRow, int targetColumn){
		
		Celda celdas[][] = table.getTablero();
		boolean noCayoTrampa=true; //si esta en false cayo en trampa.
		Class<? extends Elemento> tipo = null;
		if (celdas[sourceRow][sourceColumn]!=null){
			if(celdas[sourceRow][sourceColumn].getElemento()!=null){
				if(celdas[targetRow][targetColumn]!=null){
					if(celdas[targetRow][targetColumn].getElemento()!=null){
					}else{
						tipo = celdas[sourceRow][sourceColumn].getElemento().getClass();
						if (tipo == EspejoSimple.class || tipo == EspejoSemi.class || tipo==EspejoDoble.class){
							Celda nueva = new Celda();
							nueva = celdas[sourceRow][sourceColumn];
							table.agregarCelda(nueva, targetRow, targetColumn);
							table.borrarCelda(sourceRow, sourceColumn);
							table.borrarLasersDibujados();
							try {
								noCayoTrampa = table.agregarLasers();
								if(!noCayoTrampa){
									JOptionPane.showMessageDialog(this,
											"Ha Perdido!",
											"Suerte en la proxima",
											JOptionPane.ERROR_MESSAGE);
									GamePanel.this.frame.remove(GamePanel.this);
					                GamePanel.this.panel.setVisible(true);
					                Toolkit toolkit = getToolkit();
					                Dimension size = toolkit.getScreenSize();
					                GamePanel.this.frame.setBounds(size.width/2 - 400/2, size.height/2 - 400/2, 400, 400);
					                updateUI();
								}
							} catch (OrigenException e) {
								e.printStackTrace();
							}
							catch (LaserException e) {
								e.printStackTrace();
							}
							for(int i=0; i<table.getFilas(); i++){
								for(int j=0; j<table.getColumnas(); j++){
									try{
										bp.clearImage(i, j);
										Set<Image> imgLasers = null;
										imgLasers = celdas[i][j].dibujarLasers();
										for (Image img1 : imgLasers){
											bp.appendImage(i, j, img1);
										}
										bp.appendImage(i, j, celdas[i][j].dibujar());
									}catch(NullPointerException e2){}
								}
							}
						}
					}
				}
				else{
					tipo = celdas[sourceRow][sourceColumn].getElemento().getClass();
					if (tipo == EspejoSimple.class || tipo == EspejoSemi.class || tipo==EspejoDoble.class){
						Celda nueva = new Celda();
						nueva = celdas[sourceRow][sourceColumn];
						table.agregarCelda(nueva, targetRow, targetColumn);
						table.borrarCelda(sourceRow, sourceColumn);
						table.borrarLasersDibujados();
						try {
							noCayoTrampa = table.agregarLasers();
							if(!noCayoTrampa){
								JOptionPane.showMessageDialog(this,
										"Ha Perdido!",
										"Suerte en la proxima",
										JOptionPane.ERROR_MESSAGE);
								GamePanel.this.frame.remove(GamePanel.this);
				                GamePanel.this.panel.setVisible(true);
							}
						} catch (OrigenException e) {
							e.printStackTrace();
						}
						catch (LaserException e) {
							e.printStackTrace();
						}
						for(int i=0; i<table.getFilas(); i++){
							for(int j=0; j<table.getColumnas(); j++){
								try{
									bp.clearImage(i, j);
									Set<Image> imgLasers = null;
									imgLasers = celdas[i][j].dibujarLasers();
									for (Image img1 : imgLasers){
										bp.appendImage(i, j, img1);
									}
									bp.appendImage(i, j, celdas[i][j].dibujar());
								}catch(NullPointerException e2){}
							}
						}
					}
				}
			}
		}
		bp.repaint();
    }
}
